﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Formats.Asn1;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PatternExtensionDemo
{
    public enum AutoFocusMode
    {
        Disabled,
        Always,
        Once
    }



    public class CDPointSpec
    {

        public string Name { get; set; } = "";
    }



    public record Coordinate(int X,

    int Y,

    double Dx,

    double Dy,

    double AddrOffsetX = 0,

    double AddrOffsetY = 0);



    public class ScanSettings

    {

        public int ScanWidth { get; set; }



        public double Brightness { get; set; }



        public double Constrast { get; set; }



        public double FOV { get; set; }



        public double Rotation { get; set; }



        public int DotAvg { get; set; }



        public int LineAvg { get; set; }



        public int FrameAvg { get; set; }



        public int WaitTime { get; set; }



        public bool IsAbcEnabled { get; set; }



        public int AbcMethod { get; set; }



        public int AbcLevel { get; set; }

    }


    public class AutoFocusParam

    {

        public AutoFocusMode Mode { get; set; }



        public int DotAvg { get; set; }



        public int LineAvg { get; set; }



        public int FrameAvg { get; set; }



        public double Dx { get; set; }



        public double Dy { get; set; }



        public double FOV { get; set; }



        public int WaitTime { get; set; }

    }

    public class PreDoseOptions

    {

        public bool IsEnabled { get; set; }



        public int WaitTime { get; set; }



        public double FOV { get; set; }



        public int AccVoltage { get; set; }

    }

    public class ImageInfo

    {

        public string ImagePath { get; set; }



        public byte[] ImageData { get; set; }



        public int Height { get; set; }

        public int Width { get; set; }

    }

    public class ReferenceOptions

    {

        public ScanSettings ScanSettings { get; set; } = new();



        public AutoFocusParam AutoFocusParam { get; set; } = new();



        public PreDoseOptions PreDoseOptions { get; set; } = new();



        public bool DoCentering { get; set; }


        public string? ImagePath { get; set; }

    }

    public class AddressingOptions : ConfigBase

    {

        public ScanSettings ScanSettings { get; set; } = new();



        public AutoFocusParam AutoFocusParam { get; set; } = new();



        public PreDoseOptions PreDoseOptions { get; set; } = new();


        public string? ImagePath { get; set; }

    }





    [JsonConverter(typeof(PatternConverter))]
    public class Pattern
    {

        public int Id { get; set; }

        /// <summary>
        /// 0:OM-光学显微镜,1:SEM-扫描电子显微镜,2:MP
        /// </summary>

        public int Kind { set; get; }


        public int Ordinal { get; set; }


        public double Dx { get; set; }


        public double Dy { get; set; }


        public double AddrOffsetX { get; set; }


        public double AddrOffsetY { get; set; }


        public ReferenceOptions Reference { get; set; } = null!;


        public AddressingOptions Addressing { get; set; } = null!;

        public List<CDPointSpec> CDPoints { get; set; } = [];


        public List<string> Names { get; set; } = [];


        public bool UseAddressing { get; set; }

        public List<Coordinate>? Coordinates { get; set; }


        public bool UseDifferentialDrive { get; set; }


        public int? ParentId { get; set; }


        public int RecipeId { get; set; }

        // 独立的 Threshold 配置
        public ThresholdConfig ThresholdConfig { get; set; } = new();

    }

    // 所有可扩展配置类的基类
    public abstract class ConfigBase
    {
        // 版本号，用于数据迁移
        public int Version { get; set; } = 1;

        // 动态扩展字段（存储未知或未来新增的JSON属性）
        [JsonExtensionData]
        public Dictionary<string, object> ExtensionData { get; set; } = new();

        // 反序列化后的迁移逻辑（由子类实现）
        public virtual void Migrate() { }
    }

    // 独立的 Threshold 配置
    public class ThresholdConfig : ConfigBase
    {
        public int Threshold { get; set; }

        // 未来新增参数
        public int? Sensitivity { get; set; }

        // 反序列化后自动迁移旧数据
        public override void Migrate()
        {
            if (Version < 2)
            {
                // 假设旧版本中 Sensitivity 未定义，需要从扩展数据迁移
                if (ExtensionData.TryGetValue("Sensitivity", out var sensitivity))
                {
                    Sensitivity = Convert.ToInt32(sensitivity);
                    ExtensionData.Remove("Sensitivity");
                }
                Version = 2;
            }
        }
    }


    public class PatternConverter : JsonConverter<Pattern>
    {
        public override Pattern ReadJson(
            JsonReader reader,
            Type objectType,
            Pattern existingValue,
            bool hasExistingValue,
            JsonSerializer serializer)
        {
            var jsonObject = JObject.Load(reader);
            var pattern = new Pattern();

            // 反序列化已知字段
            serializer.Populate(jsonObject.CreateReader(), pattern);

            // 兼容性迁移：将旧版 Addressing.Threshold 迁移到 ThresholdConfig
            if (jsonObject["Addressing"]?["Threshold"] is JToken legacyThreshold)
            {
                pattern.ThresholdConfig.Threshold = legacyThreshold.Value<int>();
            }

            // 触发所有配置类的迁移逻辑
            pattern.ThresholdConfig.Migrate();
            pattern.Addressing.Migrate();
            //pattern.Reference.Migrate();
            return pattern;
        }

        public override void WriteJson(JsonWriter writer, Pattern value, JsonSerializer serializer)
        {
            // 确保旧版 Threshold 字段被写入以兼容历史系统（可选）
            var jsonObject = JObject.FromObject(value, serializer);
            jsonObject["Addressing"]["Threshold"] = value.ThresholdConfig.Threshold;
            jsonObject.WriteTo(writer);
        }
    }
}
